/*
 * Copyright (c) www.bugull.com
 */

package com.bugull.farm.core.handler;

import com.bugull.farm.core.frame.exception.BuguException;
import com.bugull.farm.core.frame.structure.Frame;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.logging.log4j.*;

/**
 * Handler for device, it checks company code and auth code.
 *
 * As the last handler, it handle the exception.
 *
 * @author Frank Wen(xbwen@hotmail.com)
 */
public abstract class AbstractDeviceFrameHandler extends SimpleChannelInboundHandler<Frame> {

    protected final static Logger logger = LogManager.getLogger(AbstractDeviceFrameHandler.class);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Frame msg) throws Exception{
    	processFrame(ctx, msg);
    }

    protected abstract void processFrame(ChannelHandlerContext ctx, Frame frame) throws Exception;

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    	cause.printStackTrace();
		logger.error("Channel closed beacuse an exception caught : " + cause);
		Channel ch = ctx.channel();
		if (cause instanceof BuguException) {
			BuguException e = (BuguException) cause;
			if (ch.isActive()) {
				ctx.writeAndFlush(e.getErrorResponse()).addListener(ChannelFutureListener.CLOSE);			
			}
		} else {
			if (ch.isActive()) {
	            ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
	        }
		}
    }

}
